home *** CD-ROM | disk | FTP | other *** search
/ Chip 2003 October / Chip Ekim 2003.iso / prog / share / tod / setup.exe / scrctl.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-04-15  |  10.5 KB  |  472 lines

  1. #include "tod.h"
  2. #include "hgrcos.h"
  3. #include <string.h>
  4.  
  5. /* Format of screen control word:
  6.  
  7.                   3322222222221111 1111110000000000
  8.                   1098765432109876 5432109876543210
  9.                   |||||||||||||||| ||||||||||||||||
  10.                  -+||||||||||||||| |||||||||||||||+-clockwise
  11.                  --+|||||||||||||| ||||||||||||||+--counterclockwise
  12.                  ---+||||||||||||| |||||||||||||+---out
  13.                  ----+|||||||||||| ||||||||||||+----in
  14.                       |||||||||||| ||||||||||||
  15.                    ---+||||||||||| |||||||||||+--- spin down
  16.                    ----+|||||||||| ||||||||||+---- spin up
  17.                    -----+||||||||| |||||||||+----- sinus amp -
  18.                    ------+|||||||| ||||||||+------ sinus amp +
  19.                           |||||||| ||||||||
  20.                      -----+||||||| |||||||+----- shift right
  21.                      ------+|||||| ||||||+------ shift left
  22.                      -------+||||| |||||+------- shear \
  23.                      --------+|||| ||||+-------- shear /
  24.                               |||| ||||
  25.                        -------+||| |||+------- shear )
  26.                        --------+|| ||+-------- shear (
  27.                   heat ---------+| |+--------- shear Z
  28.                  noise ----------+ +---------- shear S
  29.  
  30. */
  31.  
  32.  
  33.  
  34. /* ASSUMES unsigned int is the 32-bit datatype */
  35. void CtlWord2Screen(ScreenPos *pos, unsigned int ctlword)
  36. {
  37.   if(ctlword & 0x00000001)
  38.     pos->dtheta += 0x400000 / VIRTUAL_FPS;
  39.   if(ctlword & 0x00000002)
  40.     pos->dtheta -= 0x400000 / VIRTUAL_FPS;
  41.   if(ctlword & 0x00000004)
  42.     pos->dscale -= 0x20000 / VIRTUAL_FPS;
  43.   if(ctlword & 0x00000008)
  44.     pos->dscale += 0x20000 / VIRTUAL_FPS;
  45.   if(ctlword & 0x00000010)
  46.     pos->dphi -= 0x190000 / VIRTUAL_FPS;
  47.   if(ctlword & 0x00000020)
  48.     pos->dphi += 0x190000 / VIRTUAL_FPS;
  49.   if(ctlword & 0x00000040)
  50.     pos->damp -= 0x20000 / VIRTUAL_FPS;
  51.   if(ctlword & 0x00000080)
  52.     pos->damp += 0x20000 / VIRTUAL_FPS;
  53.   if(ctlword & 0x00000100)
  54.     pos->dd -= 0x6000 / VIRTUAL_FPS;
  55.   if(ctlword & 0x00000200)
  56.     pos->dd += 0x6000 / VIRTUAL_FPS;
  57.   if(ctlword & 0x00000400)
  58.     pos->dc -= 0x8000 / VIRTUAL_FPS;
  59.   if(ctlword & 0x00000800)
  60.     pos->dc += 0x8000 / VIRTUAL_FPS;
  61.   if(ctlword & 0x00001000)
  62.     pos->db -= 0xe000 / VIRTUAL_FPS;
  63.   if(ctlword & 0x00002000)
  64.     pos->db += 0xe000 / VIRTUAL_FPS;
  65.   if(ctlword & 0x00004000)
  66.     pos->da -= 0x14000 / VIRTUAL_FPS;
  67.   if(ctlword & 0x00008000)
  68.     pos->da += 0x14000 / VIRTUAL_FPS;
  69.   if(ctlword & 0x00010000)
  70.     pos->noise += 0x10000 / VIRTUAL_FPS;
  71.   if(ctlword & 0x00020000)
  72.     pos->heat += 0x400 / VIRTUAL_FPS;
  73.   if(ctlword & 0x00040000)
  74.     ;
  75.   if(ctlword & 0x00080000)
  76.     ;
  77.  
  78. }
  79.  
  80. static const int ctlword_keys[32] =
  81. {
  82.   0, 0, 0, 0,
  83.   0, 0, 0, 0,
  84.   0, 0, 0, 0,
  85.   0, 0, 0, 0,
  86.   KEY_Q, KEY_A, KEY_W, KEY_S,
  87.   KEY_E, KEY_D, KEY_R, KEY_F,
  88.   KEY_C, KEY_V, KEY_T, KEY_G,
  89.   KEY_I, KEY_K, KEY_J, KEY_L
  90. };
  91.  
  92.  
  93. unsigned int Keys2CtlWord(void)
  94. {
  95.   unsigned int a = 0;
  96.   unsigned int i;
  97.  
  98.   for(i = 0; i < 32; i++)
  99.   {
  100.     a <<= 1;
  101.     if(ctlword_keys[i])
  102.       if(key[ctlword_keys[i]])
  103.         a++;
  104.   }
  105.   return a;
  106. }
  107.  
  108.  
  109.  
  110. /*
  111. static const int morph_lands[][2] =
  112. {
  113.   { 16,  1},
  114.   { 32,  1}, // he got flat baby
  115.   { 40,  1},
  116.   { 48,  1}, // a hot kiss honey
  117.   { 56,  1},
  118.   { 64,  1}, // i'm such a swine baby
  119.   { 72,  1},
  120.   { 76,  1},
  121.   { 80,  1},
  122.   { 88,  1}, // a hot buzz baby
  123.   { 92,  1},
  124.   { 96,  1},
  125.   {104,  1},
  126.   {108,  1}
  127. };
  128.  
  129. static const int idltd_lands[][2] =
  130. {
  131.   { 32,  1},
  132.   { 48,  1},
  133.   { 64,  2},
  134.   { 80,  2},
  135.   { 96,  1}, // you and i are underdosed and we're
  136.   {104,  1}, // ready to fall
  137.   {112,  1}, // raised to be stupid taught to be
  138.   {120,  1}, // nothing at all
  139.   {132,  1},
  140.   {138,  1},
  141.   {144,  1},
  142.   {149,  1},
  143.   {154,  1},
  144.   {158,  1},
  145.   {162,  1},
  146.   {166,  1},
  147.   {170,  1},
  148.   {174,  1},
  149.   {177,  1},
  150.   {180,  1},
  151.   {183,  1},
  152.   {186,  1},
  153.   {189,  1},
  154.   {192,  1}
  155. };
  156.  
  157. static const int pressure_lands[][2] =
  158. {
  159.   { 44,  1}, // pace yourself
  160.   { 60,  1}, // everybody else
  161.   { 76,  2},
  162.   { 92,  2}, 
  163.   { 96,  1}, // so far
  164.   {112,  1},
  165.   {120,  1},
  166.   {128,  1},
  167.   {136,  1},
  168.   {144,  1}, // pressure
  169.   {148,  1},
  170.   {152,  1},
  171.   {156,  1},
  172.   {160,  1}, // pressure
  173.   {164,  1},
  174.   {168,  1},
  175.   {172,  1},
  176.   {176,  2}, // pressure
  177.   {180,  2},
  178.   {184,  2},
  179.   {188,  2},
  180.   {192,  2}, // pressure
  181.   {196,  2},
  182.   {200,  2}
  183. };
  184. */
  185. typedef struct Song
  186. {
  187.   char title[32];
  188.   char play1st[32];
  189.   char name[32];
  190.   char lands[32];
  191. } Song;
  192.  
  193. static const Song songs[2] =
  194. {
  195.   { "I Don't Like", "IDLTD_INTRO", "IDLTD_MID", "IDLTD_MANA" },
  196.   { "Kalinka", "KALINKA_INTRO", "KALINKA_MID", "KALINKA_MANA" }
  197. /*
  198.   { "Morphine", "no", "MORPHINE_MID",
  199.     (sizeof(morph_lands) / sizeof(morph_lands[0])), morph_lands },
  200.   { "Pressure", "no", "PRESSURE_MID",
  201.     (sizeof(pressure_lands) / sizeof(pressure_lands[0])), pressure_lands }
  202. */
  203. };
  204.  
  205. static int intoLoop = 0;
  206. static DATAFILE *songdat;
  207.  
  208. int intro_lands[1024], loop_lands[1024];
  209. int intro_len, loop_len;
  210.  
  211. void LoadLands(int songNo, DATAFILE *dat)
  212. {
  213.   DATAFILE *item;
  214.   char *linebuf;
  215.   const char *tok;
  216.   int inLoop = 0;
  217.  
  218.   intro_len = loop_len = 0;
  219.  
  220.   item = find_datafile_object(dat, songs[songNo].lands);
  221.   if(!item)
  222.     return;
  223.  
  224.   linebuf = malloc(item->size + 1);
  225.   if(!linebuf)
  226.     return;
  227.  
  228.   memcpy(linebuf, item->dat, item->size);
  229.   linebuf[item->size + 1] = 0;
  230.  
  231.  
  232.   for(tok = strtok(linebuf, " ,\n"); tok != 0; tok = strtok(0, " ,\n"))
  233.   {
  234.     /* look for spacer */
  235.     if(tok[0] == '=')
  236.       inLoop = 1;
  237.     else
  238.     {
  239.       int n = strtol(tok, NULL, 10);
  240.       if(n > 0)
  241.       {
  242.         if(inLoop)
  243.           loop_lands[loop_len++] = n;
  244.         else
  245.           intro_lands[intro_len++] = n;
  246.       }
  247.     }
  248.   }
  249.   free(linebuf);
  250. }
  251.  
  252.  
  253. #define TOTAL_EFFECTS 10
  254.  
  255. void StartSong(int songNo, DATAFILE *dat, ScreenPos *pos)
  256. {
  257.   static const int initEffect[TOTAL_EFFECTS] = {0, 1, 2, 7, 9, 8, 5, 4, 6, 3};
  258.  
  259.   MIDI *mid = GetResource(dat, songs[songNo].play1st);
  260.   int i;
  261.  
  262.  
  263.   LoadLands(songNo, dat);
  264.  
  265.   if(mid)
  266.     play_midi(mid, FALSE);
  267.  
  268.   songdat = dat;
  269.  
  270.   pos->lastBeat = -1;
  271.   intoLoop = 0;
  272.   pos->midiLoop = 0;
  273.   pos->curSong = songNo;
  274.   pos->mana = 0;
  275.   for(i = 0; i < nPlayers; i++)
  276.   {
  277.     pos->a = pos->da = pos->b = pos->db = pos->phi = pos->dphi = 0;
  278.     pos->c = pos->dc = pos->d = pos->dd = pos->amp = pos->damp = 0;
  279.     pos->theta = pos->dtheta = pos->dscale = pos->heat = 0;
  280.     pos->noise = 0x400000;
  281.   }
  282.  
  283.   for(i = 0; i < TOTAL_EFFECTS; i++)
  284.     pos->fxQueue[i] = initEffect[i];
  285. }
  286.  
  287.  
  288. static int compare_ints(const void *ckey, const void *celem)
  289. {
  290.   int curBeat = *(const int *)ckey;
  291.   int thatBeat = *(const int *)celem;
  292.  
  293.   return curBeat - thatBeat;
  294. }
  295.  
  296. unsigned int Mana2CtlWord(ScreenPos *pos, unsigned int beat)
  297. {
  298.   unsigned ctl = 0;
  299.   int *found;
  300.   int i;
  301.   int *song_lands;
  302.   int song_len;
  303.  
  304.   if(intoLoop == 0)
  305.   {
  306.     song_lands = intro_lands;
  307.     song_len = intro_len;
  308.  
  309.     if(midi_pos < 0)
  310.     {
  311.       MIDI *mid = GetResource(songdat, songs[pos->curSong].name);
  312.  
  313.       if(mid)
  314.         play_midi(mid, TRUE);
  315.       intoLoop = 1;
  316.     }
  317.   }
  318.   else
  319.   {
  320.     song_lands = loop_lands;
  321.     song_len = loop_len;
  322.   }
  323.  
  324.   // build keys
  325.   i = pos->nEffects;
  326.   while(i-- > 0)
  327.   {
  328.     switch(pos->fxQueue[i])
  329.     {
  330.       case 0:
  331.         if(pos->dtheta > 0)
  332.           ctl |= 0x00000001;
  333.         else
  334.           ctl |= 0x00000002;
  335.         break;
  336.       case 1:
  337.         if(pos->dscale < 0)
  338.           ctl |= 0x00000004;
  339.         else
  340.           ctl |= 0x00000008;
  341.         break;
  342.       case 2:
  343.         if(pos->dphi < 0)
  344.           ctl |= 0x00000010;
  345.         else
  346.           ctl |= 0x00000020;
  347.         break;
  348.       case 3:
  349.         if(pos->damp < 0)
  350.           ctl |= 0x00000040;
  351.         else
  352.           ctl |= 0x00000080;
  353.         break;
  354.       case 4:
  355.         if(pos->dd < 0)
  356.           ctl |= 0x00000100;
  357.         else
  358.           ctl |= 0x00000200;
  359.         break;
  360.       case 5:
  361.         if(pos->dc < 0)
  362.           ctl |= 0x00000400;
  363.         else
  364.           ctl |= 0x00000800;
  365.         break;
  366.       case 6:
  367.         if(pos->db < 0)
  368.           ctl |= 0x00001000;
  369.         else
  370.           ctl |= 0x00002000;
  371.         break;
  372.       case 7:
  373.         if(pos->da < 0)
  374.           ctl |= 0x00004000;
  375.         else
  376.           ctl |= 0x00008000;
  377.         break;
  378.       case 8:
  379.         ctl |= 0x00010000;
  380.         break;
  381.       case 9:
  382.         ctl |= 0x00020000;
  383.         break;
  384.     }
  385.   }
  386.  
  387.   if(beat == pos->lastBeat)
  388.     return ctl;
  389.  
  390.   if(beat < pos->lastBeat)
  391.     pos->midiLoop++;
  392.   pos->lastBeat = beat;
  393.  
  394.   if(beat < song_lands[0])
  395.   {
  396.     pos->nEffects = 0;
  397.     return 0;
  398.   }
  399.  
  400.   pos->nEffects = (pos->mana + 7) / 8;
  401.   if(pos->nEffects > 7)
  402.     pos->nEffects = 7;
  403.   pos->mana -= pos->nEffects;
  404.  
  405.  
  406.   found = bsearch(&beat, song_lands, song_len,
  407.                   sizeof(int), compare_ints);
  408.   if(found)
  409.   {
  410.     int maxEffect = pos->midiLoop * 2;
  411.     int r1, r2;
  412.  
  413.     if(maxEffect > TOTAL_EFFECTS)   // switch effects
  414.       maxEffect = TOTAL_EFFECTS;
  415.     r1 = rand() % maxEffect;
  416.     r2 = pos->fxQueue[0];
  417.     pos->fxQueue[0] = pos->fxQueue[1];
  418.     pos->fxQueue[1] = pos->fxQueue[r1];
  419.     pos->fxQueue[r1] = r2;
  420.  
  421.     pos->mana += pos->midiLoop; // collect mana
  422.  
  423.     pos->nEffects = 1;
  424.   }
  425.  
  426.   return ctl;
  427. }
  428.  
  429.  
  430. void Resonance(ScreenPos *pos)
  431. {
  432.   pos->fricCounter -= VIRTUAL_FPS;
  433.  
  434.   if(pos->scale < 0) // flip
  435.   {
  436.     pos->scale = -pos->scale;
  437.     pos->dscale = -pos->dscale;
  438.     pos->theta = (pos->theta & 0xffffff) ^ 0x801000;
  439.   }
  440.   pos->dscale = (pos->dscale + (54614 - pos->scale)) * 19/20;
  441.   pos->da = pos->da * 15/16;
  442.   pos->db = pos->db * 15/16;
  443.   pos->dc = pos->dc * 15/16;
  444.   pos->dd = pos->dd * 15/16;
  445.   pos->damp = pos->damp * 15/16;
  446.   pos->dtheta = pos->dtheta * 31/32; /* momentum for spinning needs low friction */
  447.   pos->dphi = pos->dphi * 63/64;
  448.  
  449.   pos->da -= pos->a / 4;
  450.   pos->db -= pos->b / 4;
  451.   pos->dc -= pos->c / 4;
  452.   pos->dd -= pos->d / 4;
  453.   pos->damp -= pos->amp / 8;
  454.   pos->dtheta -= hgrsin(pos->theta) * 32; /* the so-called "weeble mode" */
  455.   pos->dphi -= hgrsin(pos->phi) * 32;
  456.  
  457.   if(pos->midiLoop < 1)
  458.   {
  459.     pos->da = pos->da * 15/16;
  460.     pos->db = pos->db * 15/16;
  461.     pos->dc = pos->dc * 15/16;
  462.     pos->dd = pos->dd * 15/16;
  463.     pos->damp = pos->damp * 15/16;
  464.     pos->dtheta = pos->dtheta * 31/32;
  465.     pos->dphi = pos->dphi * 63/64;
  466.   }
  467.  
  468.   pos->noise = pos->noise * 9/10;
  469.   pos->heat = pos->heat * 9/10;
  470. }
  471.  
  472.